package services

import (
	"easyShop/core/config"
	"fmt"
	"github.com/golang-jwt/jwt/v4"
	"time"
)

func JwtEncode(data interface{}) (string, error) {
	// Create a new token object, specifying signing method and the claims
	// you would like it to contain.

	myClaims := jwt.MapClaims{
		"foo": "bar",
		"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
		"exp": time.Now().Add(time.Hour * 30).Unix(),
	}
	switch data.(type) {
	case map[string]interface{}:
		for k, v := range data.(map[string]interface{}) {
			myClaims[k] = v
		}
	default:
		myClaims["data"] = data
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, myClaims)

	mySigningKey := []byte(config.GetConfig("jwt.private_key").(string))
	// Sign and get the complete encoded token as a string using the secret
	tokenString, err := token.SignedString(mySigningKey)

	return tokenString, err
}

func JwtDecode(tokenString string) (jwt.MapClaims, error) {
	// Parse takes the token string and a function for looking up the key. The latter is especially
	// useful if you use multiple keys for your application.  The standard is to use 'kid' in the
	// head of the token to identify which key to use, but the parsed token (head and claims) is provided
	// to the callback, providing flexibility.
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}

		// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
		return []byte(config.GetConfig("jwt.private_key").(string)), nil
	})

	if claims, ok := token.Claims.(jwt.MapClaims); err == nil && ok && token.Valid {
		return claims, nil
	} else {
		return nil, nil
	}
}
